package com.zmn.oms.zmn.normal.business.impl.order;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.zmn.base.common.data.common.dro.area.AreaDRO;
import com.zmn.base.product.common.consts.BaseProductConsts;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.Option;
import com.zmn.common.dto2.OptionData;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.manager.redis.RedisManager;
import com.zmn.oms.business.impl.order.OrderBaseBServiceImpl;
import com.zmn.oms.business.interfaces.factory.OrderFactorySimpleBService;
import com.zmn.oms.business.interfaces.order.DuplicateOrderBService;
import com.zmn.oms.business.interfaces.work.orderpay.FactoryAccountModifyBService;
import com.zmn.oms.common.annotation.ZsNormalOrderWorkLog;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderLogConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.constant.RedisKeyConsts;
import com.zmn.oms.common.dto.OmsOperator;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.exception.OmsBusinessException;
import com.zmn.oms.model.bo.order.BatchFactoryUploadBO;
import com.zmn.oms.model.bo.order.OrderBO;
import com.zmn.oms.model.dto.order.OrderDTO;
import com.zmn.oms.model.dto.order.zmn.FactoryBatchNewOrderDIO;
import com.zmn.oms.model.dto.work.modify.DuplicateOrderDTO;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.factory.OrderFactory;
import com.zmn.oms.model.entity.order.Order;
import com.zmn.oms.model.entity.product.OrderProduct;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.base.oms.common.model.es.orderwork.EsOrderWork;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.state.WorkAutoFlowBService;
import com.zmn.oms.zmn.normal.business.interfaces.order.FactoryOrderBatchBService;
import org.apache.commons.lang3.StringUtils;
import org.apache.curator.shaded.com.google.common.collect.Lists;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author sunlife
 * @date:2020/7/3 4:21 下午
 * description:
 */
@Service
public class FactoryOrderBatchBServiceImpl extends OrderBaseBServiceImpl implements FactoryOrderBatchBService {

    @Autowired
    private OrderFactorySimpleBService orderFactorySimpleBService;
    @Autowired
    private FactoryOrderBatchBService factoryOrderBatchBService;
    @Autowired
    private DuplicateOrderBService duplicateOrderBService;
    @Autowired
    private RedisManager redisManager;
    @Autowired
    private FactoryAccountModifyBService factoryAccountModifyBService;
    @Resource(name="flowConfirmBService")
    WorkAutoFlowBService<OrderWork> flowConfirmBService;

    static ExecutorService executorService = Executors.newCachedThreadPool();


    @Override
    @Transactional(rollbackFor = Exception.class)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_INPUT)
    public OrderBO insertOrder(FactoryBatchNewOrderDIO factoryBatchNewOrderDIO) throws OmsBaseException {
        if (Objects.nonNull(factoryBatchNewOrderDIO.getDutyTime()) && DateUtil.getNowTimestamp() > DateUtil.toTimestamp(factoryBatchNewOrderDIO.getDutyTime())) {
            factoryBatchNewOrderDIO.setDutyTime(null);
        }

        // 检查重复单
        EsOrderWork duplicateOrder = this.checkDuplicate(factoryBatchNewOrderDIO);

        // 复制订单信息
        Order order = BeanMapper.map(factoryBatchNewOrderDIO, Order.class);
        OrderDetail orderDetail = BeanMapper.map(factoryBatchNewOrderDIO, OrderDetail.class);

        OrderProduct product = new OrderProduct();
        product.setBrandId(GlobalConsts.NONE);
        product.setNumber(factoryBatchNewOrderDIO.getCount());
        product.setProductId(factoryBatchNewOrderDIO.getProductId());
        product.setRemark(factoryBatchNewOrderDIO.getFault());
        List<OrderProduct> orderProductList = Lists.newArrayList(product);

        // 厂商订单信息
        OrderFactory orderFactory = BeanMapper.map(factoryBatchNewOrderDIO, OrderFactory.class);
        orderFactory.setFcOrderId(order.getOrderId());

        // 工单
        OrderWork orderWork = BeanMapper.map(factoryBatchNewOrderDIO, OrderWork.class);

        // 重复单信息
        if (Objects.nonNull(duplicateOrder)) {
            orderWork.setDuplicate(GlobalConsts.YES);
            orderWork.setDuplicateId(duplicateOrder.getId());
        }

        // 渠道ID
        orderWork.setChannelId(factoryBatchNewOrderDIO.getChannelId());
        orderWork.setSourceChannelId(factoryBatchNewOrderDIO.getChannelId());
        orderFactory.setFcUserId(factoryBatchNewOrderDIO.getFactoryUserId());

        // 设置默认信息
        order.setPlat(Optional.ofNullable(factoryBatchNewOrderDIO.getPlat()).orElse(GlobalConsts.PLAT_MARK_YEYX));
        if (!Objects.equals(OrderConsts.ORDER_TYPE_REWORK, factoryBatchNewOrderDIO.getType())) {
            factoryBatchNewOrderDIO.setPlatWork(order.getPlat());
        }

        // 用户ID是厂商ID
        order.setUserId((long)orderFactory.getFactoryId());
        order.setSourceType(OrderConsts.ORDER_SOURCE_TYPE_FACTORY);
        order.setTest(GlobalConsts.NO);
        order.setResultStatus(OrderStatusConsts.WORK_RESULT_DOING);

        orderWork.setInputType(factoryBatchNewOrderDIO.getInputType());
        orderWork.setReceiverId(factoryBatchNewOrderDIO.getOperatorId());
        orderWork.setCreater(factoryBatchNewOrderDIO.getOperator());
        orderWork.setReceiveTime(DateUtil.getNow());

        // 订单信息
        OrderDTO orderDTO = BeanMapper.map(factoryBatchNewOrderDIO, OrderDTO.class);
        orderDTO.setOrder(order);
        orderDTO.setOrderDetail(orderDetail);
        orderDTO.setOrderProductList(orderProductList);
        orderDTO.setOrderWork(orderWork);
        orderDTO.setOrderFactory(orderFactory);

        // 订单处理
        simpleOrderBService.processOrder(orderDTO);
        // 录入状态
        order.setStatus(OrderStatusConsts.ORDER_STATUS_INPUT);
        // 厂商单处理
        orderFactorySimpleBService.processOrderFactory(orderDTO);
        // 工单处理
        orderWorkBService.processOrderWork(orderDTO);

        // 保存订单
        OrderBO orderBO = simpleOrderBService.insertOrder(orderDTO);

        // 计算原价
        super.setOriginalAmount(orderDTO.getOrderWork(), null);

        // 冻结金额
        super.saveFactoryFreezeAmount(orderDTO);

        // 操作日志处理
        if (StringUtils.isNotBlank(orderDetail.getRemark())) {
            if (StringUtils.isNotBlank(factoryBatchNewOrderDIO.getOperatorRemark())) {
                factoryBatchNewOrderDIO.setOperatorRemark(String.format("订单备注：%s；%s", factoryBatchNewOrderDIO.getOperatorRemark(), orderDetail.getRemark()));
            } else {
                factoryBatchNewOrderDIO.setOperatorRemark(String.format("订单备注：%s", orderDetail.getRemark()));
            }
        }

        // 返回处理
        factoryBatchNewOrderDIO.setOrderId(orderBO.getOrderWork().getOrderId());
        factoryBatchNewOrderDIO.setWorkId(orderBO.getOrderWork().getWorkId());

        return orderBO;
    }

    @Override
    public void batchInsertOrder(List<FactoryBatchNewOrderDIO> orders) throws OmsBaseException {
        for (FactoryBatchNewOrderDIO order: orders) {
            OrderBO orderBO = factoryOrderBatchBService.insertOrder(order);

            // 确认自动流转
            this.autoFlowConfirm(orderBO);
        }
    }

    @Override
    public void batchInsertOrder(List<FactoryBatchNewOrderDIO> orders, Long operatorId, String operator, Integer operatorType) throws OmsBaseException {
        // 完善厂商用户信息 factoryUserId
        /*Integer factoryId = orders.get(0).getFactoryId();

        // 渠道ID
        ResponseDTO<FactoryDRO> responseDTO = factoryListRemoteService.getFactoryById(factoryId);
        FactoryDRO factoryDRO = responseDTO.getData();
        if (factoryDRO == null) {
            throw new OmsBaseException(responseDTO.getMessage());
        }
        if (NumberUtil.isNullOrZero(factoryDRO.getUserId())) {
            throw new OmsBaseException("厂商用户不存在");
        }

        // 校验厂商剩余金额是否允许下单
        verifyFactoryFreezePermit(orders, factoryDRO, operatorId, operator, operatorType);

        // 完善地址信息 城市名称、省份名称、省份ID
        List<Integer> areaIds = orders.stream().map(FactoryBatchNewOrderDIO::getCityId).distinct().collect(Collectors.toList());
        List<Integer> countyIds = orders.stream().map(FactoryBatchNewOrderDIO::getCountyId).distinct().collect(Collectors.toList());
        areaIds.addAll(countyIds);

        List<AreaDRO> citys = new ArrayList<>(areaIds.size());
        List<List<Integer>> partitionList = com.google.common.collect.Lists.partition(areaIds, 300);
        for (List<Integer> list : partitionList) {
            ResponseDTO<List<AreaDRO>> listResponseDTO = areaListRemoteService.listAreaByIds(list);
            if (CollectionUtil.isNotNullOrEmpty(listResponseDTO.getData())) {
                citys.addAll(listResponseDTO.getData());
            }
        }


        // 方便后续获取 转型为map  提取省份ID，查询省份信息
        Map<Integer, AreaDRO> areaMap = citys.stream().collect(Collectors.toMap(AreaDRO::getAreaId, areaDRO -> areaDRO));
        List<Integer> provinceIds = citys.stream().map(AreaDRO::getParentId).distinct().collect(Collectors.toList());

        List<AreaDRO> provinceResponseList = new ArrayList<>(provinceIds.size());
        List<List<Integer>> partitionProvinceList = com.google.common.collect.Lists.partition(provinceIds, 300);
        for (List<Integer> list : partitionProvinceList) {
            ResponseDTO<List<AreaDRO>> listResponseDTO = areaListRemoteService.listAreaByIds(list);
            if (CollectionUtil.isNotNullOrEmpty(listResponseDTO.getData())) {
                provinceResponseList.addAll(listResponseDTO.getData());
            }
        }

        areaMap.putAll(provinceResponseList.stream().collect(Collectors.toMap(AreaDRO::getAreaId, areaDRO -> areaDRO)));
        int size = orders.size();

        Set<Object> checkDuplicateSet = Sets.newConcurrentHashSet();

        for (int i = 0; i < size; i++) {
            if (i >= 100) {
                break;
            }
            FactoryBatchNewOrderDIO dio = orders.get(i);

            try {
                dio.setType(OrderConsts.ORDER_TYPE_NEW);
                dio.setOperatorType(operatorType);
                dio.setOperatorId(operatorId);
                dio.setOperator(operator);

                dio.setFactoryUserId(factoryDRO.getUserId());

                AreaDRO city = areaMap.get(dio.getCityId());
                AreaDRO county = areaMap.get(dio.getCountyId());
                AreaDRO province = areaMap.get(city.getParentId());

                dio.setCityName(city.getName());
                dio.setCountyName(county.getName());
                dio.setProvinceId(province.getAreaId());
                dio.setProvinceName(province.getName());

                dio.setOperator(operator);
                dio.setOperatorId(operatorId);
                dio.setOperatorType(operatorType);

                String key1 = String.format("%s-%s-%s", dio.getTelephone(), dio.getBizType(), dio.getProductId());
                logger.info("#批量录入厂商单 -1[{}]：{}", i, key1);
                if (checkDuplicateSet.contains(key1)) {
                    logger.info("#批量录入厂商单 重复数据-1[{}]：{}-", i, key1);
                    throw new OmsBusinessException("成功录入：" + (i) + "单，第：" + (i + 1) + "条数据重复");
                }
                checkDuplicateSet.add(key1);

                if (StringUtils.isNotBlank(dio.getTelephone2())) {
                    String key2 = String.format("%s-%s-%s", dio.getTelephone2(), dio.getBizType(), dio.getProductId());
                    logger.info("#批量录入厂商单 -2[{}]：{}", i, key2);
                    if (checkDuplicateSet.contains(key2)) {
                        logger.info("#批量录入厂商单 重复数据-2[{}]：{}", i, key2);
                        throw new OmsBusinessException("成功录入：" + (i) + "单，第：" + (i + 1) + "条数据重复");
                    }
                    checkDuplicateSet.add(key2);
                }

                OrderBO orderBO = factoryOrderBatchBService.insertOrder(dio);

                // 确认自动流转
                this.autoFlowConfirm(orderBO);

            } catch (OmsBaseException e) {
                throw new OmsBaseException("成功录入前：" + (i) + "单，第：" + (i + 1) + "单录入有误:" + e.getMessage());
            }
        }*/

    }

    /**
     * 自动确认流转
     *
     * @param orderBO
     * @return
     */
    @Override
    public void autoFlowConfirm(OrderBO orderBO){
        OrderWork orderWork = orderBO.getOrderWork();
        OrderDetail orderDetail = orderBO.getOrderDetail();

        // logger.info("自动确认-orderWork-{}", JSON.toJSONString(orderWork));
        // logger.info("自动确认-orderDetail-{}", JSON.toJSONString(orderDetail));

        // 当订单“业务线&产品组&前后台产品分类（一级和二级）”为空时，不能确认，包括：自动确认、人工确认
        if (NumberUtil.isNullOrZero(orderWork.getBizLine())
                || NumberUtil.isNullOrZero(orderWork.getServProductGroupId())
                || NumberUtil.isNullOrZero(orderWork.getCategId())
                || NumberUtil.isNullOrZero(orderWork.getShowCategId())) {
            // logger.info("{}-{}-{}-{}", orderWork.getBizLine(), orderWork.getServProductGroupId(), orderWork.getCategId(), orderWork.getShowCategId());
            return;
        }

        if (Objects.equals(com.zmn.consts.GlobalConsts.BIZ_TYPE_F, orderWork.getBizType())) {
            // F单有城市，也可确认，包括：人工和系统确认，包括：API过来的F端订单；
            // TODO liuying  以及非厂商的一些特殊渠道，如：天猫
            // logger.info("countyId={}", orderDetail.getCountyId());
            if (NumberUtil.isNullOrZero(orderDetail.getCountyId())) {
                return;
            }
        } else {
            // logger.info("latitude={}", orderDetail.getLatitude());
            if (Objects.isNull(orderDetail.getLatitude()) || orderDetail.getLatitude() == 0d) {
                return;
            }

            // 预约时间为空
            if (Objects.isNull(orderWork.getDutyTime())) {
                return;
            }
        }

        // 开始流转
        flowConfirmBService.execute(orderWork);
    }

    @Override
    public void batchInsertOrder(Sheet sheet, Integer factoryId, Long operatorId, String operator, Integer operatorType, String batchId) throws OmsBaseException {

        /*verifyTableHead(sheet);

        List<FactoryBatchNewOrderDIO> orders = getOrders(sheet);

        // 数据处理
        // 渠道ID
        ResponseDTO<FactoryDRO> responseDTO = factoryListRemoteService.getFactoryById(factoryId);
        FactoryDRO factoryDRO = responseDTO.getData();
        if (factoryDRO == null) {
            throw new OmsBaseException(responseDTO.getMessage());
        }
        if (NumberUtil.isNullOrZero(factoryDRO.getUserId())) {
            throw new OmsBaseException("厂商用户不存在");
        }

        // 校验厂商剩余金额是否允许下单
        verifyFactoryFreezePermit(orders, factoryDRO, operatorId, operator, operatorType);

        executorService.submit(new Runnable() {
            @Override
            public void run() {

                // redis key
                String redisKey = String.format(RedisKeyConsts.ORDER_UPLOAD_KEY, String.valueOf(batchId));
                BatchFactoryUploadBO uploadBO = new BatchFactoryUploadBO();

                List<String> productNames = orders.stream().map(FactoryBatchNewOrderDIO::getProductName).distinct().collect(Collectors.toList());

                // 调用接口获取对应数据
                logger.info("#批量录入厂商单 获取产品入参：{}", JSON.toJSONString(productNames));
                ResponseDTO<OptionData<Integer>> productResponse = productForeignListRemoteService.listOptionByNameList(productNames, BaseProductConsts.ERP_SHOW_TYPE);
                logger.info("#批量录入厂商单 获取产品出参：{}", JSON.toJSONString(productResponse));

                if (!productResponse.isSuccess()) {
                    uploadBO.updateStatus(true, true, productResponse.getMessage(), NumberUtil.divAndToPercent(0, 1));
                    redisManager.setex(redisKey, JSON.toJSONString(uploadBO), 60 * 60);
                    return;
                }

                List<Option<Integer>> productBaseDROS = null;
                if (Objects.isNull(productResponse.getData()) || CollectionUtil.isNullOrEmpty(productResponse.getData().getOptions())) {
                    productBaseDROS = Collections.EMPTY_LIST;
                }

                // 判断是否有重复的产品，如果有，不允许录入厂商单
                Map<String, Long> collect = productBaseDROS
                        .stream()
                        .map(Option::getLabel)
                        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
                List<String> repeatProductName = Lists.newArrayList();
                collect.forEach((productName, count) -> {
                    if (count > 1) {
                        repeatProductName.add(productName);
                    }
                });
                if (repeatProductName.size() > 0) {
                    String exceptionInfo = String.format("导入失败，原因：[%s]产品配置重复，请核实", repeatProductName.stream().collect(Collectors.joining(",")));
                    uploadBO.updateStatus(true, true, exceptionInfo, "0");
                    redisManager.setex(redisKey, JSON.toJSONString(uploadBO), 60 * 60);
                    return;
                }

                Map<String, Option<Integer>> productMap = CollectionUtil.isNullOrEmpty(productBaseDROS) ? Maps.newHashMap() :  productBaseDROS.stream().collect(Collectors.toMap(Option::getLabel, e -> e));
                Set<Object> checkDuplicateSet = Sets.newConcurrentHashSet();

                for (int i = 0; i < orders.size(); i++ ) {
                    if (i >= 100) {
                        uploadBO.updateStatus(true, true, "已导入100单，100单以后不导入", NumberUtil.divAndToPercent(orders.size(), orders.size()));
                        redisManager.setex(redisKey, JSON.toJSONString(uploadBO), 60 * 60);
                        break;
                    }
                    FactoryBatchNewOrderDIO order = orders.get(i);

                    uploadBO.setProgressRate(NumberUtil.divAndToPercent(i + 1, orders.size()));
                    redisManager.setex(redisKey, JSON.toJSONString(uploadBO), 60 * 60);

                    try {
                        // 校验本行数据
                        verifyOrderData(order);

                        order.setType(OrderConsts.ORDER_TYPE_NEW);
                        order.setOperatorType(operatorType);
                        order.setOperatorId(operatorId);
                        order.setOperator(operator);

                        order.setFactoryId(factoryId);
                        order.setChannelId(factoryDRO.getChannelId());
                        order.setFactoryUserId(factoryDRO.getUserId());

                        String cityInfo = order.getCityInfo();
                        String cityName = null;
                        AreaDRO city = null;
                        AreaDRO county = null;
                        if (NumberUtil.isNumber(cityInfo)) {
                            // ID
                            logger.info("#批量录入厂商单 获取城市入参：{}", JSON.toJSONString(cityInfo));
                            ResponseDTO<AreaDRO> cityResponse = areaListRemoteService.getById(NumberUtil.toInteger(cityInfo));
                            logger.info("#批量录入厂商单 获取城市出参：{}", JSON.toJSONString(cityResponse));
                            if (cityResponse.isSuccess() && Objects.nonNull(cityResponse.getData())) {
                                cityName = cityResponse.getData().getName();
                            }
                        } else {
                            cityName = cityInfo;
                        }

                        logger.info("#批量录入厂商单 获取城市入参：{}", JSON.toJSONString(cityInfo));
                        ResponseDTO<List<AreaDRO>> cityResponse = areaListRemoteService.listAreaByCityNameList(Lists.newArrayList(cityName));
                        logger.info("#批量录入厂商单 获取城市出参：{}", JSON.toJSONString(cityResponse));
                        if (cityResponse.isSuccess() && CollectionUtil.isNotNullOrEmpty(cityResponse.getData())) {
                            city = cityResponse.getData().get(0);
                        }

                        if (city != null) {
                            order.setCityId(city.getCityId());
                            order.setCityName(city.getCityName());
                            order.setProvinceId(city.getProvinceId());
                            order.setProvinceName(city.getProvinceName());
                        } else {
                            throw new OmsBaseException("无法根据【" + cityName + "】获取城市信息");
                        }

                        Integer cityId = city.getCityId();

                        logger.info("#批量录入厂商单 获取区县入参：{}", JSON.toJSONString(order.getCountyName()));
                        ResponseDTO<List<AreaDRO>> countyResponse = areaListRemoteService.getAreaByName(order.getCountyName());
                        logger.info("#批量录入厂商单 获取区县出参：{}", JSON.toJSONString(countyResponse));
                        if (cityResponse.isSuccess()) {
                            if (countyResponse.getData().size() == 1) {
                                county = countyResponse.getData().get(0);
                            } else {
                                Optional<AreaDRO> countyOptional = countyResponse.getData().stream().filter(item -> {
                                    return Objects.equals(item.getParentId(),cityId);
                                }).findFirst();
                                if (countyOptional.isPresent()) {
                                    county = countyOptional.get();
                                }
                            }
                        }

                        if (county != null) {
                            if (Objects.equals(county.getParentId(), city.getCityId())) {
                                order.setCountyId(county.getAreaId());
                                order.setLatitude(Double.valueOf(county.getLatitude()));
                                order.setLongitude(Double.valueOf(county.getLongitude()));
                            } else {
                                throw new OmsBaseException(order.getCountyName() + "不是" + order.getCityName() + "下的区县");
                            }
                        } else {
                            throw new OmsBaseException("无法根据【" +order.getCountyName() + "】获取区县信息");
                        }

                        Option<Integer> product = productMap.get(order.getProductName());
                        if (product != null) {
                            order.setProductId(product.getValue());
                        } else {
                            throw new OmsBaseException("【" + order.getProductName() + "】不是一个标准的产品名称");
                        }

                        String key1 = String.format("%s-%s-%s", order.getTelephone(), order.getBizType(), order.getProductId());
                        logger.info("#批量录入厂商单-1[{}]：{}", i, key1);
                        if (checkDuplicateSet.contains(key1)) {
                            logger.info("#批量录入厂商单-1-重复数据[{}]：{}", i, key1);
                            throw new OmsBusinessException("成功录入：" + (i) + "单，第：" + (i + 2) + "条数据重复");
                        }
                        checkDuplicateSet.add(key1);

                        if (StringUtils.isNotBlank(order.getTelephone2())) {
                            String key2 = String.format("%s-%s-%s", order.getTelephone2(), order.getBizType(), order.getProductId());
                            logger.info("#批量录入厂商单-2[{}]：{}", i, key2);
                            if (checkDuplicateSet.contains(key2)) {
                                logger.info("#批量录入厂商单-2-重复数据[{}]：{}", i, key2);
                                throw new OmsBusinessException("成功录入：" + (i) + "单，第：" + (i + 2) + "条数据重复");
                            }
                            checkDuplicateSet.add(key2);
                        }

                        OrderBO orderBO = factoryOrderBatchBService.insertOrder(order);

                        // 确认自动流转
                        factoryOrderBatchBService.autoFlowConfirm(orderBO);

                    } catch (OmsBusinessException e) {
                        uploadBO.updateStatus(true, true, e.getMessage(), NumberUtil.divAndToPercent(i + 1, orders.size()));
                        redisManager.setex(redisKey, JSON.toJSONString(uploadBO), 60 * 60);
                        break;
                    } catch (OmsBaseException e) {
                        String exceptionInfo = "成功导入：" + (i) + "单，第：" + (i + 2) + "行数据有误:" + e.getMessage();
                        uploadBO.updateStatus(true, true, exceptionInfo, NumberUtil.divAndToPercent(i + 1, orders.size()));
                        redisManager.setex(redisKey, JSON.toJSONString(uploadBO), 60 * 60);
                        break;
                    }
                }
                if (!uploadBO.isEndFlag()) {
                    uploadBO.setEndFlag(true);
                    uploadBO.setMessage("成功导入："+ orders.size() +"单");
                }
                redisManager.setex(redisKey, JSON.toJSONString(uploadBO), 60 * 60);
            }
        });*/

    }

    private List<FactoryBatchNewOrderDIO> getOrders(Sheet sheet) {
        List<FactoryBatchNewOrderDIO> orders = new ArrayList<>();
        FactoryBatchNewOrderDIO order = null;
        // 遍历sheet
        for (Row r : sheet) {
            if (r.getRowNum() < 1) {
                continue;
            }
            if (r.getRowNum() >=101) {
                break;
            }
            String userName = getCellValue(r.getCell(0));
            String telephone = getCellValue(r.getCell(1));
            String telephone2 = getCellValue(r.getCell(2));
            String bizType = getCellValue(r.getCell(3));
            String city = getCellValue(r.getCell(4));
            String county = getCellValue(r.getCell(5));
            String address = getCellValue(r.getCell(6));
            String product = getCellValue(r.getCell(7));
            String number = getCellValue(r.getCell(8));
            String fault = getCellValue(r.getCell(10));
            String remark = getCellValue(r.getCell(11));

            if (StringUtil.isBlank(telephone) &&
                    StringUtil.isBlank(bizType) &&
                    StringUtil.isBlank(city) &&
                    StringUtil.isBlank(county) &&
                    StringUtil.isBlank(address) &&
                    StringUtil.isBlank(product) &&
                    StringUtil.isBlank(number) &&
                    r.getCell(9) == null
            ) {
                continue;
            }

            order = new FactoryBatchNewOrderDIO();

            // 用户名
            order.setUserName(userName);

            // 用户电话
            order.setTelephone(telephone);
            order.setTelephone2(telephone2);

            if ((r.getCell(3) != null)) {
                order.setBizType(getBizType(bizType));
            }
            order.setCityInfo(city);
            order.setCountyName(county);

            order.setAddress(address);
            order.setProductName(product);

            if (NumberUtil.isNumber(number)) {
                order.setCount(Integer.parseInt(number));
            }

            if (r.getCell(9) != null) {
                Date dutyTime = r.getCell(9).getDateCellValue();
                order.setDutyTime(dutyTime);
            }
            order.setFault(fault);
            order.setRemark(remark);

            orders.add(order);
        }
        return orders;
    }

    private Integer getBizType(String typeStr) {
        typeStr = StringUtils.trim(typeStr);
        if (Objects.equals("F-保内业务", typeStr)) {
            return com.zmn.consts.GlobalConsts.BIZ_TYPE_F;
        } else if (Objects.equals("C-保外业务", typeStr)) {
            return com.zmn.consts.GlobalConsts.BIZ_TYPE_C;
        } else if (Objects.equals("B-工程业务", typeStr)) {
            return com.zmn.consts.GlobalConsts.BIZ_TYPE_B;
        }

        return GlobalConsts.NONE;
    }

    private String getCellValue(Cell cell) {
        if (cell == null) {
            return "";
        }
        cell.setCellType(CellType.STRING);
        return cell.getStringCellValue().trim();
    }

    private void verifyTableHead(Sheet sheet) throws OmsBaseException {
        Row r = sheet.getRow(0);
        String userName = getCellValue(r.getCell(0));
        String telephone = getCellValue(r.getCell(1));
        String telephone2 = getCellValue(r.getCell(2));
        String bizType = getCellValue(r.getCell(3));
        String city = getCellValue(r.getCell(4));
        String county = getCellValue(r.getCell(5));
        String address = getCellValue(r.getCell(6));
        String product = getCellValue(r.getCell(7));
        String number = getCellValue(r.getCell(8));
        String dutyTime = getCellValue(r.getCell(9));
        String fault = getCellValue(r.getCell(10));
        String remark = getCellValue(r.getCell(11));
        if (!Objects.equals(userName, "姓名") ||
                !Objects.equals(telephone, "* 用户电话1") ||
                !Objects.equals(telephone2, "用户电话2") ||
                !Objects.equals(bizType, "* 业务类型") ||
                !Objects.equals(city, "* 城市") ||
                !Objects.equals(county, "* 区") ||
                !Objects.equals(address, "* 地址") ||
                !Objects.equals(product, "* 服务产品") ||
                !Objects.equals(number, "* 数量") ||
                !Objects.equals(dutyTime, "预约时间") ||
                !Objects.equals(fault, "其他故障") ||
                !Objects.equals(remark, "下单备注")
        ) {
            throw new OmsBaseException("excel文件表头数据有误，请参照模板");
        }
    }

    private void verifyOrderData(FactoryBatchNewOrderDIO order) throws OmsBaseException {
        String telephone = order.getTelephone();
        Integer bizType = order.getBizType();
        String cityInfo = order.getCityInfo();
        String address = order.getAddress();
        String productName = order.getProductName();
        Integer count = order.getCount();
        String remark = order.getRemark();

        if (!StringUtil.isMobile(telephone)) {
            throw new OmsBaseException("手机号格式不正确，请修改");
        }
        if (Objects.isNull(bizType) || bizType == GlobalConsts.NONE) {
            throw new OmsBaseException("保修类型不能为空，请修改");
        }
        if (StringUtil.isBlank(cityInfo)) {
            throw new OmsBaseException("城市不能为空，请修改");
        }
        if (StringUtil.isBlank(address) || address.length()>50 ) {
            throw new OmsBaseException("地址不能为空且长度不能大于50，请修改");
        }
        if (StringUtil.isBlank(productName)) {
            throw new OmsBaseException("产品不能为空，请修改");
        }
        if (NumberUtil.isNullOrZero(count) || count > 10) {
            throw new OmsBaseException("数量必须是正整数，而且≤10，请修改");
        }
        if (StringUtil.isNotBlank(remark) && remark.length() > 500) {
            throw new OmsBaseException("备注字数必须小于500，请修改");
        }
    }

    /*private void verifyFactoryFreezePermit(List<FactoryBatchNewOrderDIO> orders, FactoryDRO factoryDRO, Long operatorId, String operator, Integer operatorType) throws OmsBaseException {

        List<FactoryBatchNewOrderDIO> warrantyInOrders = orders.stream().filter(order -> Objects.equals(order.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_F)).collect(Collectors.toList());

        if (warrantyInOrders.size() > 0) {

            Integer shouldFreezeAmount = 0;
            for (FactoryBatchNewOrderDIO order : warrantyInOrders) {
                shouldFreezeAmount += Optional.ofNullable(factoryDRO.getForzenAmount()).orElse(15000) * order.getCount();
            }
            OmsOperator omsOperator = new OmsOperator();
            omsOperator.setOperator(operator);
            omsOperator.setOperatorId(operatorId);
            omsOperator.setOperatorType(operatorType);

            factoryAccountModifyBService.verifyFactoryFreezePermit(factoryDRO, shouldFreezeAmount, omsOperator);
        }
    }*/

    @Override
    public BatchFactoryUploadBO getImportingProgress(String batchId) {
        BatchFactoryUploadBO uploadBO;
        // redis key
        String redisKey = String.format(RedisKeyConsts.ORDER_UPLOAD_KEY, String.valueOf(batchId));
        if (redisManager.exists(redisKey)) {
            return JSON.parseObject(redisManager.get(redisKey), BatchFactoryUploadBO.class);
        } else {
            uploadBO = new BatchFactoryUploadBO();
            uploadBO.setEndFlag(true);
            return uploadBO;
        }
    }

    /**
     * 重复单检查
     *
     * @param factoryNewOrderDTO
     * @return 重复单信息
     * @throws OmsBaseException
     */
    private EsOrderWork checkDuplicate(FactoryBatchNewOrderDIO factoryNewOrderDTO) throws OmsBaseException {
        Objects.requireNonNull(factoryNewOrderDTO, "订单信息不能为空");

        if (!Objects.equals(factoryNewOrderDTO.getType(), OrderConsts.ORDER_TYPE_NEW)) {
            return null;
        }



        return null;
    }

    public static void main(String[] args) {
        HashSet<Object> checkDuplicateSet = Sets.newHashSet();
        checkDuplicateSet.add("1");
        System.out.println(checkDuplicateSet.add("2"));

    }
}
